// ObjectPanel.cpp : implementation file
//

#include "StdAfx.h"
#include "ObjectPanel.h"

#include "Objects\BaseObject.h"
#include "LayersSelectDialog.h"
#include "Material\Material.h"
#include "SegmentedWorld/SegmentedWorldManager.h"

/////////////////////////////////////////////////////////////////////////////
// CObjectPanel dialog


CObjectPanel::CObjectPanel(CWnd* pParent )
	: CXTResizeDialog(CObjectPanel::IDD, pParent)
{
	//{{AFX_DATA_INIT(CObjectPanel)
	m_name = _T("");
	//m_flatten = FALSE;
	//m_bShared = FALSE;
	//}}AFX_DATA_INIT
	m_obj = 0;
	m_multiSelect = false;
	m_currentLayer = GuidUtil::NullGuid;

	GetIEditor()->GetObjectManager()->GetLayersManager()->AddUpdateListener( functor(*this,&CObjectPanel::OnLayerUpdate) );
}

CObjectPanel::~CObjectPanel()
{
	GetIEditor()->GetObjectManager()->GetLayersManager()->RemoveUpdateListener( functor(*this,&CObjectPanel::OnLayerUpdate) );
}


void CObjectPanel::DoDataExchange(CDataExchange* pDX)
{
	CXTResizeDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CObjectPanel)
	DDX_Control(pDX, IDC_OBJECT_COLOR, m_colorCtrl);
	DDX_Text(pDX, IDC_OBJECT_NAME, m_name);
	//DDX_Check(pDX, IDC_FLATTEN, m_flatten);
	//DDX_Check(pDX, IDC_SHARED, m_bShared);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_OBJECT_NAME, m_nameCtrl);
	//DDX_Control(pDX, IDC_FLATTEN, m_flattenCtrl);
	//DDX_Control(pDX, IDC_SHARED, m_sharedCtrl);
	DDX_Control(pDX, IDC_LAYER, m_layerBtn);
	DDX_Control(pDX, IDC_LAYER_NAME, m_layerName);
	DDX_Control(pDX, IDC_MATERIAL, m_mtlBtn);
	DDX_Control(pDX, IDC_SPEC, m_specCombo);
}


BEGIN_MESSAGE_MAP(CObjectPanel, CXTResizeDialog)
	//{{AFX_MSG_MAP(CObjectPanel)
	ON_WM_DRAWITEM()
	ON_BN_CLICKED(IDC_OBJECT_COLOR, OnObjectColor)
	ON_WM_KEYDOWN()
	//ON_EN_UPDATE(IDC_OBJECT_NAME,OnUpdate)
	ON_EN_UPDATE(IDC_OBJECT_AREA,OnUpdate)
	ON_EN_UPDATE(IDC_OBJECT_HELPER,OnUpdate)
	//ON_BN_CLICKED(IDC_SHARED, OnShared)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_LAYER, OnBnClickedLayer)
	//ON_EN_KILLFOCUS(IDC_OBJECT_NAME, OnChangeName)
	ON_BN_CLICKED(IDC_MATERIAL, OnBnClickedMaterial)
	ON_CBN_SELENDOK(IDC_SPEC,OnMinSpecChange)
	ON_STN_CLICKED(IDC_LAYER_NAME, OnBnClickedLayer)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CObjectPanel message handlers

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::SetMultiSelect( bool bEnable )
{
	m_multiSelect = bEnable;

	if (bEnable)
	{
		//m_sharedCtrl.SetButtonStyle(BS_AUTO3STATE);
		//m_flattenCtrl.SetButtonStyle(BS_AUTO3STATE);
		m_nameCtrl.EnableWindow(FALSE);
		//m_sharedCtrl.SetCheck(2);
		//m_flattenCtrl.SetCheck(2);
		m_area.EnableWindow(FALSE);
		SetLayerGuidAndName();
		m_helperSize.EnableWindow(FALSE);
		m_mtlBtn.EnableWindow( FALSE );
		m_mtlBtn.SetWindowText( "" );
	}else
	{
		m_nameCtrl.EnableWindow(TRUE);
		m_helperSize.EnableWindow(TRUE);
		m_mtlBtn.EnableWindow( TRUE );
		//m_sharedCtrl.SetButtonStyle(BS_AUTOCHECKBOX);
		//m_flattenCtrl.SetButtonStyle(BS_AUTOCHECKBOX);
	}
}

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::SetParams( CBaseObject *obj, const SParams &params )
{
	if (obj != m_obj && m_obj)
	{
		UpdateData(TRUE);
		OnUpdate();
	}
	m_obj = obj;

	COLORREF col = m_color;

	m_name = params.name;
	m_color = params.color;
	m_area.SetValue( params.area );
	m_helperSize.SetValue( params.helperScale );
	//m_flatten = params.flatten;
	//m_bShared = params.shared;

	UpdateData(FALSE);

	if (m_obj && m_obj->GetMaterial())
	{
		//m_mtlBtn.EnableWindow( TRUE );
		m_mtlBtn.SetWindowText( m_obj->GetMaterial()->GetName() );
	}
	else
	{
		//m_mtlBtn.EnableWindow( FALSE );
		if (m_obj)
			m_mtlBtn.SetWindowText( "<No Custom Material>" );
		else
			m_mtlBtn.SetWindowText( "" );
	}

	m_currentLayer = params.layerGUID;

	// Find layer from id.
	CObjectLayer* pLayer = GetIEditor()->GetObjectManager()->GetLayersManager()->FindLayer(params.layerGUID);

	if (pLayer)
	{
		m_currentLayer = pLayer->GetGUID();
		CString text = pLayer->GetFullPathName();
		if(pLayer->IsModified())
			text+="*";
		m_layerName.SetWindowText( text );
	}
	else
	{
		m_currentLayer = GuidUtil::NullGuid;
		m_layerName.SetWindowText( "" );
	}

	if (col != m_color)
	{
		GetDlgItem(IDC_OBJECT_COLOR)->RedrawWindow();
		//RedrawWindow();
	}
	if (params.minSpec == CONFIG_DETAIL_SPEC)
		m_specCombo.SetCurSel(5);
	else
		m_specCombo.SetCurSel(params.minSpec);
}

void CObjectPanel::GetParams( SParams &params )
{
	UpdateData(TRUE);
	params.name = m_name;
	params.color = m_color;
	params.area = m_area.GetValue();
	params.helperScale = m_helperSize.GetValue();
	//params.flatten = m_flatten;
	//params.shared = m_bShared;
	params.layerGUID = m_currentLayer;

	int spec = m_specCombo.GetCurSel();
	if (spec == 5)
		params.minSpec = CONFIG_DETAIL_SPEC;
	else
		params.minSpec = spec;
}

void CObjectPanel::SetEnable(bool bEnable)
{
	m_colorCtrl.EnableWindow(bEnable);
	m_nameCtrl.EnableWindow(bEnable);
	m_layerBtn.EnableWindow(bEnable);
	m_mtlBtn.EnableWindow(bEnable);
	m_specCombo.EnableWindow(bEnable);
	m_area.EnableWindow(bEnable);
	m_helperSize.EnableWindow(bEnable);
	UpdateData(FALSE);
}

void CObjectPanel::SetEnableMultiSel(bool bEnable, bool bAllOfSameType)
{
	m_nameCtrl.EnableWindow(FALSE);
	m_area.EnableWindow(FALSE);
	m_helperSize.EnableWindow(FALSE);
	m_mtlBtn.EnableWindow( FALSE );

	m_colorCtrl.EnableWindow(bEnable);
	m_layerBtn.EnableWindow(bEnable);
	m_specCombo.EnableWindow(bEnable);
	UpdateData(FALSE);
}

void CObjectPanel::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	// TODO: Add your message handler code here and/or call default
	if (nIDCtl == IDC_OBJECT_COLOR)
	{
		CDC dc;
		dc.Attach( lpDrawItemStruct->hDC );
		CBrush brush( m_color );
		CPen pen( PS_SOLID,1,RGB(1,1,1) );
		CBrush *prevBrush = dc.SelectObject( &brush );
		CPen *prevPen = dc.SelectObject( &pen );
		dc.Rectangle( &lpDrawItemStruct->rcItem );
		dc.SelectObject( prevBrush );
		dc.SelectObject( prevPen );
		dc.Detach();
		return;
	}
	
	CXTResizeDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

void CObjectPanel::OnObjectColor() 
{
	// TODO: Add your control notification handler code here
	COLORREF col = m_color;
	if (GetIEditor()->SelectColor(col,this))
	{
		m_color = col;
		m_colorCtrl.RedrawWindow();
		OnUpdate();

		if (m_multiSelect)
		{
			CUndo undo("Set Color");
			// Update shared flags in current selection group.
			CSelectionGroup *selection = GetIEditor()->GetSelection();
			for (int i = 0; i < selection->GetCount(); i++)
			{
				selection->GetObject(i)->ChangeColor(m_color);
				SW_ON_OBJ_MOD(selection->GetObject(i));
			}
		}
		else
		{
			SW_ON_OBJ_MOD(m_obj);
		}
	}
}

void CObjectPanel::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CXTResizeDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL CObjectPanel::OnInitDialog() 
{
	CXTResizeDialog::OnInitDialog();
	
	m_area.Create( this,IDC_OBJECT_AREA );
	m_layerBtn.SetIcon( MAKEINTRESOURCE(IDI_LAYERS) );

	m_helperSize.Create( this,IDC_OBJECT_HELPER );
	m_helperSize.SetRange( 0.01f,1000 );

	SetResize( IDC_OBJECT_NAME,SZ_HORRESIZE(1) );
	SetResize( IDC_LAYER_NAME,SZ_HORRESIZE(1) );
	SetResize( IDC_MATERIAL,SZ_HORRESIZE(1) );
	SetResize( IDC_OBJECT_COLOR,SZ_HORREPOS(1) );

	m_specCombo.AddString( "All" );
	m_specCombo.AddString( "Low" );
#if !defined(IS_CRYDEV)
	m_specCombo.AddString( "Medium/Console" );


#endif

	m_specCombo.AddString( "High" );
	m_specCombo.AddString( "Very High" );
	//m_specCombo.AddString( "Detail" );
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CObjectPanel::OnUpdate()
{
	if (m_obj)
		m_obj->OnUIUpdate();
}

/*
void CObjectPanel::OnShared() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	OnUpdate();

	if (m_multiSelect)
	{
		CUndo undo("Set Shared");
		// Update shared flags in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		for (int i = 0; i < selection->GetCount(); i++)
		{
			selection->GetObject(i)->SetShared(m_bShared);
		}
	}
}
*/

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnUpdateName()
{
	//UpdateData(TRUE);
	//OnUpdate();

	/*
	if (m_multiSelect)
	{
		CUndo undo("Set Name");
		// Update shared flags in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		for (int i = 0; i < selection->GetCount(); i++)
		{
			selection->GetObject(i)->SetName(m_name);
		}
	}
	*/
}

/*
//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnUpdateFlatten()
{
	UpdateData(TRUE);
	OnUpdate();

	if (m_multiSelect)
	{
		CUndo undo("Set Flatten");
		// Update shared flags in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		for (int i = 0; i < selection->GetCount(); i++)
		{
			//OBJFLAG_FLATTEN
			if (m_flatten)
				selection->GetObject(i)->SetFlags( OBJFLAG_FLATTEN );
			else
				selection->GetObject(i)->ClearFlags( OBJFLAG_FLATTEN );
		}
	}
}
*/
//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnUpdateArea()
{
	UpdateData(TRUE);
	OnUpdate();

	if (m_multiSelect)
	{
		CUndo undo("Set Area");
		// Update shared flags in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		for (int i = 0; i < selection->GetCount(); i++)
		{
			selection->GetObject(i)->SetArea(m_area.GetValue());
			SW_ON_OBJ_MOD(selection->GetObject(i));
		}
	}
	else
	{
		SW_ON_OBJ_MOD(m_obj);
	}

}
void CObjectPanel::OnBnClickedLayer()
{
	// Open Layer selection dialog.
	CRect rc;
	m_layerBtn.GetWindowRect(rc);
	CLayersSelectDialog dlg( CPoint(rc.left-40,rc.bottom) );

	dlg.SetSelectedLayer( m_currentLayer );
	if (dlg.DoModal() == IDOK)
	{
		GUID selLayer = dlg.GetSelectedLayer();
		if (selLayer != GuidUtil::NullGuid && selLayer != m_currentLayer)
		{
			CObjectLayer* pLayer=0;

			GUID selNewLayer;
			CObjectLayer* pNewLayer=0;
			selNewLayer = dlg.GetSelectedLayer();
			pNewLayer = GetIEditor()->GetObjectManager()->GetLayersManager()->FindLayer(selNewLayer);

#ifdef SEG_WORLD
			CSelectionGroup *selection = GetIEditor()->GetSelection();
			for (int i = 0; i < selection->GetCount(); i++)
			{
				CBaseObject* pObject = selection->GetObject(i);
				SW_TEST_OBJ_MOVETO(pObject, pObject->GetPos(), pNewLayer, false);
			}
#endif

			if((pLayer = GetIEditor()->GetObjectManager()->GetLayersManager()->FindLayer(m_currentLayer)))
				pLayer->SetModified();

			pLayer = GetIEditor()->GetObjectManager()->GetLayersManager()->FindLayer(selLayer);
			if (!pLayer)
				return;

			pLayer->SetModified();
			m_currentLayer = selLayer;

			CUndo undo("Set Object Layer");
			if (m_multiSelect)
			{
				// Update shared flags in current selection group.
				CSelectionGroup *selection = GetIEditor()->GetSelection();
				for (int i = 0; i < selection->GetCount(); i++)
				{
					CBaseObject* pObject = selection->GetObject(i);
					SW_ON_OBJ_MOVETO(pObject, pObject->GetPos(), pNewLayer);
					pObject->SetLayer(pNewLayer);
				}
			}
			else
			{
				SW_ON_OBJ_MOVETO(m_obj, m_obj->GetPos(), pNewLayer);
				OnUpdate();
			}

			SetLayerGuidAndName();
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnMinSpecChange()
{
	UpdateData(TRUE);
	OnUpdate();

	if (m_multiSelect)
	{
		SParams params;
		GetParams( params );

		CUndo undo("Change MinSpec");
		// Update shared data in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();
		for (int i = 0; i < selection->GetCount(); i++)
		{
			selection->GetObject(i)->SetMinSpec(params.minSpec);
			SW_ON_OBJ_MOD(selection->GetObject(i));
		}
	}
	else
	{
		SW_ON_OBJ_MOD(m_obj);
	}
}

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnChangeName()
{	
	CUndo undo("Set Name");

	IObjectManager * pObjMan = GetIEditor()->GetObjectManager();

	if (!pObjMan)
		return;

	CString name("");
	m_nameCtrl.GetWindowText(name);

	if (m_multiSelect)
	{

		// Update shared flags in current selection group.
		CSelectionGroup *selection = GetIEditor()->GetSelection();

		for (int i = 0; i < selection->GetCount(); i++)
		{
			CBaseObject *pObject = selection->GetObject(i);

			if (!pObject)
				continue;

			if ( pObjMan->IsDuplicateObjectNameWarning(pObject,name,true) )
				return;

			pObjMan->ChangeObjectName( pObject ,name );
			SW_ON_OBJ_MOD(pObject);
		}
	}
	else
	{
		if (m_obj)
		{
			if ( m_obj->GetName().Compare(name)!=0 )
			{
				if ( pObjMan->IsDuplicateObjectNameWarning(m_obj,name,true) )
				{
					m_nameCtrl.SetWindowText(m_obj->GetName());
					return;
				}
			}
			else
			{
				return;
			}
		}

		OnUpdate();
	}
}

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnOK()
{
	// Name change.
	OnChangeName();
};

//////////////////////////////////////////////////////////////////////////
void CObjectPanel::OnBnClickedMaterial()
{
	// Select current material
	if (m_obj)
	{
		SW_ON_OBJ_MOD(m_obj);
		if (m_obj->GetMaterial())
		{
			GetIEditor()->OpenDataBaseLibrary( EDB_TYPE_MATERIAL,m_obj->GetMaterial() );
		}
		else
		{
			GetIEditor()->OpenDataBaseLibrary( EDB_TYPE_MATERIAL );
			GetIEditor()->ExecuteCommand("Material.SelectFromObject");
		}
	}
}


void CObjectPanel::OnLayerUpdate( int event,CObjectLayer *pLayer )
{
	switch (event)
	{
	case CObjectLayerManager::ON_LAYER_MODIFY:
		{
			CSelectionGroup *selection = GetIEditor()->GetSelection();
			if(selection->GetCount()==1 && selection->GetObject(0)==m_obj && m_obj->GetLayer() && m_obj->GetLayer()==pLayer)
			{
				SParams params;
				GetParams( params );
				params.layerGUID = m_obj->GetLayer()->GetGUID();
				SetParams(m_obj, params);
			}
		}
		break;
	}
}

void CObjectPanel::SetLayerGuidAndName()
{
	m_currentLayer = GuidUtil::NullGuid;
	m_layerName.SetWindowText("");

	GUID layerGuid = GuidUtil::NullGuid;
	CString layerName;
	CSelectionGroup *selection = GetIEditor()->GetSelection();
	if (NULL != selection && selection->GetCount() >= 1)
	{
		CBaseObject* firstObj = selection->GetObject(0);
		CObjectLayer* firstObjLayer = firstObj->GetLayer();
		if (NULL == firstObjLayer)
			return;

		layerName = firstObjLayer->GetFullPathName();
		layerGuid = firstObjLayer->GetGUID();

		for (int i = 1; i < selection->GetCount(); ++i)
		{
			CBaseObject* obj = selection->GetObject(i);
			CObjectLayer* layer = obj->GetLayer();
			if (NULL == layer || layerGuid != layer->GetGUID())
				return;
		}

		if (firstObjLayer->IsModified())
			layerName+="*";
	}

	m_currentLayer = layerGuid;
	m_layerName.SetWindowText(layerName);
}
